package com.lagou.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import javax.jws.soap.SOAPBinding;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.setOut;

@Activate(group = {CommonConstants.CONSUMER})
public class TPMonitorFilter implements Filter,Runnable {

    //key为耗时,value为该耗时下的数据个数,TreeMap是红黑色树数据结构实现,可在初始化时指定其key的排序规则(从小到大)
    TreeMap<Long, Integer> treeMapA =new TreeMap<>();
    TreeMap<Long, Integer> treeMapB =new TreeMap<>();;
    TreeMap<Long, Integer> treeMapC =new TreeMap<>();;
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        long   startTime  = currentTimeMillis();
        String methodName = invocation.getMethodName();

        try {
            // 执行方法
            return  invoker.invoke(invocation);
        } finally {

            if("methodA".equals(methodName)){//方法A
                Long timeA = System.currentTimeMillis()-startTime;
                System.out.println("timeA::::"+timeA);
                Integer count = (Integer) treeMapA.get(timeA);
                System.out.println("count::::"+count);
                //存储调用时间和该耗时下的次数
                if(count!=null){
                    treeMapA.put(timeA,count++);
                }else{
                    treeMapA.put(timeA,1);
                }
            }else if("methodB".equals(methodName)){//方法B
                Long timeB = System.currentTimeMillis()-startTime;
                Integer count = (Integer) treeMapB.get(timeB);
                //存储调用时间和该耗时下的次数
                if(count!=null){
                    treeMapB.put(timeB,count++);
                }else{
                    treeMapB.put(timeB,1);
                }
            }else if("methodC".equals(methodName)){//方法C
                Long timeC = System.currentTimeMillis()-startTime;
                Integer count = (Integer) treeMapC.get(timeC);
                //存储调用时间和该耗时下的次数
                if(count!=null){
                    treeMapC.put(timeC,count++);
                }else{
                    treeMapC.put(timeC,1);
                }
            }

            //System.out.println("方法名:"+methodName+"耗时"+(currentTimeMillis()-startTime) + "毫秒");
            Thread thread = new Thread(this);
            thread.start();
        }
    }

    @Override
    public void run() {
        //System.out.println("执行run方法。。");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //各个方法调用的总次数
        Collection<Integer> valuesA = treeMapA.values();
        Collection<Integer> valuesB = treeMapB.values();
        Collection<Integer> valuesC = treeMapC.values();
        int sumA = 0 ;
        int sumB = 0 ;
        int sumC = 0 ;
        for(int i=0;i<valuesA.size();i++){
            sumA = sumA+valuesA.iterator().next();
        }
        for(int i=0;i<valuesB.size();i++){
            sumB = sumB+valuesB.iterator().next();
        }
        for(int i=0;i<valuesC.size();i++){
            sumC = sumC+valuesC.iterator().next();
        }
        //System.out.println("次数11"+sumA+","+sumB+","+sumC);

        /*int sumA = treeMapA.values().stream().mapToInt(o->o).sum();
        int sumB = treeMapB.values().stream().mapToInt(o->o).sum();
        int sumC = treeMapC.values().stream().mapToInt(o->o).sum();*/
        Double idx90A= Math.ceil((double)sumA*90/100);
        Double idx99A= Math.ceil((double)sumA*99/100);
        Double idx90B= Math.ceil((double)sumB*90/100);
        Double idx99B= Math.ceil((double)sumB*99/100);
        Double idx90C= Math.ceil((double)sumC*90/100);
        Double idx99C= Math.ceil((double)sumC*99/100);
        //System.out.println("doublw"+idx90A+","+idx90B+","+idx90C);

        System.out.println("methodA的TP90:"+idx90A+", TP99:"+idx99A);
        System.out.println("methodB的TP90:"+idx90B+", TP99:"+idx99B);
        System.out.println("methodC的TP90:"+idx90C+", TP99:"+idx99C);
    }
}

